package xj.graph2d.template;

import static javax.swing.SwingConstants.HORIZONTAL;
import static javax.swing.SwingConstants.LEFT;

import java.awt.Color;
import java.util.Map;

import xj.graph2d.DrawShapeConstants;
import xj.graph2d.GraphNodeBase;
import xj.graph2d.TextShape;
import xj.graph2d.shapes.BarShape;
import xj.graph2d.shapes.BoxLabel;
import xj.graph2d.shapes.block.AttributeShape;
import xj.graph2d.shapes.block.BlockShape;
import xj.graph2d.shapes.block.ClassBlock;
import xj.graph2d.shapes.block.HBlockShape;
import xj.graph2d.shapes.block.MethodBlock;
import xj.graph2d.shapes.block.MethodDeclShape;
import xj.graph2d.shapes.block.SimpleStatementShape;

public class VisualClassTemplate 
  extends UMLTemplate {

  static String[] enumSubnodeNames = {
    "EnumValue", 
  };

  static String[] importSubnodeNames = {
    "Import", "StaticImport",
  };

  static String[] statementBlockSubnodeNames = {
    "SimpleStatement", 
    "Block", 
    "Loop1", "Loop2", "Loop3", "Loop4", 
    "If", "Switch", "Try",
  };

  public void initTools() {
    addSubnodeToolNames(name + ".EnumBlock", enumSubnodeNames);
    addSubnodeToolNames(name + ".ImportList", importSubnodeNames);

    addSubnodeToolNames(name + ".Block",  statementBlockSubnodeNames);
    addSubnodeToolNames(name + ".Loop1",  statementBlockSubnodeNames);
    addSubnodeToolNames(name + ".Loop2",  statementBlockSubnodeNames);
    addSubnodeToolNames(name + ".Loop3",  statementBlockSubnodeNames);
    addSubnodeToolNames(name + ".Loop4",  statementBlockSubnodeNames);

    addSubnodeToolNames(name + ".Case", statementBlockSubnodeNames);
    addSubnodeToolNames(name + ".CaseDefault", statementBlockSubnodeNames);

    addSubnodeToolNames(name + ".Catch", statementBlockSubnodeNames);
    addSubnodeToolNames(name + ".CatchFinally", statementBlockSubnodeNames);
  }

  @Override
  public void makeTemplate(Map iconMap) {
    BlockShape shape;
    BlockShape iconShape;

    shape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    add(new TemplateToolButton("Block", shape, 36, 30, false, true));

    SimpleStatementShape stmt = makeStatementShape();
    add(new TemplateToolButton("SimpleStatement", stmt, 36, 16, false, true));

    // while 
    shape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.WHILE_BLOCK);
    shape.addShape(makeConditionShape());
    shape.layoutComponents();

    iconShape = new BlockShape(0, 0, 200, 150);
    iconShape.setSideBarColor(new Color(0, 255, 0, 64));
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(true);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Loop1", shape, iconShape, 36, 30, false, true));

    // do-while 
    shape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.DO_WHILE_BLOCK);
    shape.addShape(makeConditionShape());
    shape.layoutComponents();

    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setSideBarColor(new Color(0, 255, 0, 64));
    iconShape.setShowFooter(true);
    iconShape.setShowSideBar(true);
    iconShape.setFooterHeight(10);
    add(new TemplateToolButton("Loop2", shape, iconShape, 36, 30, false, true));

    // basic for loop 
    shape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.FOR_BLOCK);
    shape.addShape(makeInitializationShape());
    shape.addShape(makeConditionShape());
    shape.addShape(makeIncrementShape());
    shape.layoutComponents();
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);

    iconShape.setSideBarColor(new Color(0, 255, 0, 64));
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(true);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Loop3", shape, iconShape, 36, 30, false, true));

    // enhanced for loop
    shape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.FOR_BLOCK);
    shape.addShape(makeInitializationShape());
    shape.addShape(makeIterableShape());
    shape.layoutComponents();

    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setSideBarColor(new Color(0, 255, 0, 64));
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(true);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Loop4", shape, iconShape, 36, 30, false, true));

    HBlockShape hshape = new HBlockShape(0, 0, 300, 80);
    setNodeAttr(hshape);
    setNodeColor(hshape, NODE_FG, NODE_BG);
    hshape.setBlockType(BlockShape.IF_BLOCK);
    hshape.addShape(makeConditionShape());
    // true branch 
    shape = new BlockShape(); 
    shape.setBlockType(BlockShape.TRUE_BRANCH);
    //shape.setShowSideBar(true); 
    setNodeAttr(shape);
    //setNodeColor(shape, TRUE_BRANCH_FG, TRUE_BRANCH_BG);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setMovable(false); 
    hshape.addShape(shape); 
    // false branch 
    shape = new BlockShape(); 
    shape.setBlockType(BlockShape.FALSE_BRANCH);
    //shape.setShowSideBar(true); 
    setNodeAttr(shape);
    //setNodeColor(shape, FALSE_BRANCH_FG, FALSE_BRANCH_BG);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setMovable(false); 
    //System.out.println("VisualClassTemplate @1 " + shape);
    hshape.addShape(shape); 
    hshape.doLayout();
    iconShape = new HBlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("If", hshape, iconShape, 36, 30, false, true));

    // hrizontal layout 
    hshape = makeSwitchStatementShape();
    iconShape = new HBlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Switch", hshape, iconShape, 36, 30, false, true));    

    /*
    // vertical layout 
    shape = new BlockShape(0, 0, 300, 80);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.SWITCH_BLOCK);
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Switch", shape, iconShape, 36, 30, false, true));
    */

    shape = makeCaseBranchShape(); 
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    //setNodeColor(iconShape, TRUE_BRANCH_FG, TRUE_BRANCH_BG);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setHeaderColor(new Color(0xFF, 0xD7, 0, 64));
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Case", shape, iconShape, 36, 30, false, true));

    shape = makeDefaultCaseBranchShape();
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    //setNodeColor(iconShape, FALSE_BRANCH_FG, FALSE_BRANCH_BG);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setHeaderColor(new Color(0xFF, 0xD7, 0, 64));
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("CaseDefault", shape, iconShape, 36, 30, false, true));

    // try block

    shape = makeTryBlockShape();
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Try", shape, iconShape, 36, 30, false, true));    

    shape = makeCatchShape(); 
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    //setNodeColor(iconShape, TRUE_BRANCH_FG, TRUE_BRANCH_BG);
    setNodeColor(iconShape, CATCH_FG, CATCH_BG);
    //iconShape.setHeaderColor(new Color(0xFF, 0xD7, 0, 64));
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Catch", shape, iconShape, 36, 30, false, true));

    shape = makeCatchFinallyShape();
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    //setNodeColor(iconShape, FALSE_BRANCH_FG, FALSE_BRANCH_BG);
    setNodeColor(iconShape, CATCH_FG, CATCH_BG);
    //iconShape.setHeaderColor(new Color(0xFF, 0xD7, 0, 64));
    iconShape.setShowHeader(true);
    iconShape.setShowSideBar(false);
    iconShape.setShowExpansionBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("CatchFinally", shape, iconShape, 36, 30, false, true));

    // method

    shape = makeMethodShape(false, false);
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setHeaderColor(new Color(0, 128, 0, 64));
    iconShape.setShowHeader(true);
    //iconShape.setShowSideBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Method1", shape, iconShape, 36, 30, false, true));

    shape = makeMethodShape(false, true);
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setHeaderColor(new Color(0, 128, 0, 64));
    iconShape.setShowHeader(true);
    //iconShape.setShowSideBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Method2", shape, iconShape, 36, 30, false, true));

    // constructor

    shape = makeMethodShape(true, false);
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, NODE_FG, NODE_BG);
    iconShape.setHeaderColor(new Color(0, 128, 0, 64));
    iconShape.setShowHeader(true);
    //iconShape.setShowSideBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Constructor", shape, iconShape, 36, 30, false, true));

    // parameter

    stmt = makeParameterShape();
    add(new TemplateToolButton("Parameter", stmt, 36, 16, false, true));

    // class 
    shape = makeClassShape(false);
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, CLASS_FG, CLASS_BG);
    iconShape.setHeaderColor(new Color(0, 128, 0, 64));
    iconShape.setShowHeader(true);
    //iconShape.setShowSideBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Class1", shape, iconShape, 36, 30, false, true));

    shape = makeClassShape(true);
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, CLASS_FG, CLASS_BG);
    iconShape.setHeaderColor(new Color(0, 128, 0, 64));
    iconShape.setShowHeader(true);
    //iconShape.setShowSideBar(false);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("Class2", shape, iconShape, 36, 30, false, true));

    stmt = makeAttributeShape();
    add(new TemplateToolButton("Attribute", stmt, 36, 16, false, true));

    stmt = makeConstructorDeclShape();
    add(new TemplateToolButton("ConstructorDecl", stmt, 36, 16, false, true));

    stmt = makeMethodDeclShape();
    add(new TemplateToolButton("MethodDecl", stmt, 36, 16, false, true));

    // import 
    shape = makeImportListShape();
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, IMPORT_FG, IMPORT_BG);
    iconShape.setHeaderColor(new Color(0xEE, 0x82, 0xEE, 64));
    iconShape.setShowHeader(true);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("ImportList", shape, iconShape, 36, 30, false, true));

    stmt = makeImportShape(false);
    add(new TemplateToolButton("Import", stmt, 36, 16, false, true));

    stmt = makeImportShape(true);
    add(new TemplateToolButton("StaticImport", stmt, 36, 16, false, true));

    // enum 
    shape = makeEnumBlockShape();
    iconShape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(iconShape);
    setNodeColor(iconShape, ENUM_FG, ENUM_BG);
    Color c = iconShape.getDrawAttr().getPenColor();
    iconShape.setHeaderColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), 64));
    //iconShape.setHeaderColor(new Color(0xEE, 0x82, 0xEE, 64));
    iconShape.setShowHeader(true);
    iconShape.setHeaderHeight(10);
    add(new TemplateToolButton("EnumBlock", shape, iconShape, 36, 30, false, true));

    stmt = makeEnumValueShape();
    add(new TemplateToolButton("EnumValue", stmt, 36, 16, false, true));

    // expressions 

    BarShape expr = makeExpressionShape();
    BarShape exprIcon = new BarShape(0, 0, 80, 20);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, EXPR_FG, EXPR_BG);
    exprIcon.setLeftEnd(BarShape.TRIANGLE_OUT);
    exprIcon.setRightEnd(BarShape.DEFAULT_END);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Expression", expr, exprIcon, 36, 16, false, true));

    expr = makeConditionShape();
    exprIcon = new BarShape(0, 0, 80, 18);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, COND_FG, COND_BG);
    exprIcon.setLeftEnd(BarShape.TRIANGLE_OUT);
    exprIcon.setRightEnd(BarShape.TRIANGLE_OUT);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Condition", expr, exprIcon, 36, 16, false, true));

    expr = makeInitializationShape();
    exprIcon = new BarShape(0, 0, 80, 18);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, INIT_FG, INIT_BG);
    exprIcon.setLeftEnd(BarShape.WEDGE_OUT);
    exprIcon.setRightEnd(BarShape.TRIANGLE_IN);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Initialization", expr, exprIcon, 36, 16, false, true));

    expr = makeIncrementShape();
    exprIcon = new BarShape(0, 0, 80, 18);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, INCR_FG, INCR_BG);
    exprIcon.setLeftEnd(BarShape.TRIANGLE_IN);
    exprIcon.setRightEnd(BarShape.TRIANGLE_IN);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Increment", expr, exprIcon, 36, 16, false, true));

    expr = makeIterableShape();
    exprIcon = new BarShape(0, 0, 80, 18);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, INCR_FG, INCR_BG);
    exprIcon.setLeftEnd(BarShape.TRIANGLE_OUT);
    exprIcon.setRightEnd(BarShape.TRIANGLE_IN);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Iterable", expr, exprIcon, 36, 16, false, true));

    expr = makeExceptionShape();
    exprIcon = new BarShape(0, 0, 80, 18);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, EXCEPTION_FG, EXCEPTION_BG);
    exprIcon.setLeftEnd(BarShape.TRIANGLE_IN);
    exprIcon.setRightEnd(BarShape.TRIANGLE_OUT);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Exception", expr, exprIcon, 36, 16, false, true));

    /*
    expr = new BarShape(0, 0, 80, 18);  
    expr.setLeftEnd(BarShape.CIRCLE_OUT);
    expr.setRightEnd(BarShape.CIRCLE_OUT);
    expr.setRole(BlockShape.PARAMETER);
    setNodeAttr(expr);
    setNodeColor(expr, PARAM_FG, PARAM_BG);
    text = makeTitleText("parameter", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Parameter");
    text.setMarkString(true);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_CENTER);
    expr.layoutComponents();
    exprIcon = new BarShape(0, 0, 80, 18);  
    setNodeAttr(exprIcon);
    setNodeColor(exprIcon, PARAM_FG, PARAM_BG);
    exprIcon.setLeftEnd(BarShape.CIRCLE_OUT);
    exprIcon.setRightEnd(BarShape.CIRCLE_OUT);
    exprIcon.setLeftEndSize(4);
    exprIcon.setRightEndSize(4);
    add(new TemplateToolButton("Parameter", expr, exprIcon, 36, 30, false, true));
    */
  }

  protected HBlockShape makeSwitchStatementShape() { 
    HBlockShape hshape = new HBlockShape(0, 0, 300, 80);
    setNodeAttr(hshape);
    setNodeColor(hshape, NODE_FG, NODE_BG);
    hshape.setBlockType(BlockShape.SWITCH_BLOCK);
    hshape.addShape(makeExpressionShape()); 
    hshape.addShape(makeCaseBranchShape());
    hshape.addShape(makeDefaultCaseBranchShape());
    hshape.layoutComponents();
    return hshape; 
  }

  protected BlockShape makeDefaultCaseBranchShape() { 
    BlockShape shape = new BlockShape(0, 0, 150, 80);
    setNodeAttr(shape);
    //setNodeColor(shape, FALSE_BRANCH_FG, FALSE_BRANCH_BG);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.CASE_DEFAULT);
    return shape; 
  }

  protected BlockShape makeCaseBranchShape() { 
    BlockShape shape = new BlockShape(0, 0, 150, 80);
    setNodeAttr(shape);
    //setNodeColor(shape, TRUE_BRANCH_FG, TRUE_BRANCH_BG);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.CASE_BLOCK);
    shape.addShape(makeExpressionShape()); 
    shape.layoutComponents();
    return shape; 
  }

  protected BlockShape makeTryBlockShape() { 
    BlockShape shape = new BlockShape(0, 0, 200, 150);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    shape.setBlockType(BlockShape.TRY_BLOCK);

    // body 
    BlockShape shape1 = new BlockShape();
    setNodeAttr(shape1);
    setNodeColor(shape1, NODE_FG, NODE_BG);
    shape1.setMovable(false); 
    shape.addShape(shape1); 

    // catch block 
    shape1 = new BlockShape(); 
    shape1.setBlockType(BlockShape.CATCH_LIST);
    setNodeAttr(shape1);
    setNodeColor(shape1, CATCH_FG, NODE_BG);
    shape1.setMovable(false); 
    shape.addShape(shape1); 
    shape.layoutComponents();
    return shape; 
  }

  protected BlockShape makeCatchFinallyShape() { 
    BlockShape shape = new BlockShape(0, 0, 150, 80);
    setNodeAttr(shape);
    //setNodeColor(shape, FALSE_BRANCH_FG, FALSE_BRANCH_BG);
    setNodeColor(shape, CATCH_FG, CATCH_BG);
    shape.setBlockType(BlockShape.CATCH_FINALLY);
    return shape; 
  }

  protected BlockShape makeCatchShape() { 
    BlockShape shape = new BlockShape(0, 0, 150, 80);
    setNodeAttr(shape);
    //setNodeColor(shape, TRUE_BRANCH_FG, TRUE_BRANCH_BG);
    setNodeColor(shape, CATCH_FG, CATCH_BG);
    shape.setBlockType(BlockShape.CATCH_BLOCK);
    shape.addShape(makeExceptionShape()); 
    shape.layoutComponents();
    return shape; 
  }

  protected BarShape makeExpressionShape() { 
    BarShape expr = new BarShape(0, 0, 80, 20);  
    expr.setLeftEnd(BarShape.TRIANGLE_OUT);
    expr.setRightEnd(BarShape.DEFAULT_END);
    expr.setRole(BlockShape.EXPRESSION);
    expr.setDisplayName("Expression");
    setNodeAttr(expr);
    setNodeColor(expr, EXPR_FG, EXPR_BG);
    TextShape text = null;
    text = makeTitleText("expression", true, NODE_FONT, NODE_COLOR);
    text.setDisplayName("Expression");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    expr.layoutComponents();
    return expr;
  }

  protected BarShape makeConditionShape() { 
    BarShape expr = new BarShape(0, 0, 80, 18);  
    expr.setLeftEnd(BarShape.TRIANGLE_OUT);
    expr.setRightEnd(BarShape.TRIANGLE_OUT);
    expr.setRole(BlockShape.CONDITION);
    expr.setDisplayName("Condition");
    setNodeAttr(expr);
    setNodeColor(expr, COND_FG, COND_BG);
    TextShape text = null;
    text = makeTitleText("condition", true, NODE_FONT, NODE_COLOR);
    text.setDisplayName("Condition");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    expr.layoutComponents();
    return expr;
  }

  protected BarShape makeExceptionShape() { 
    BarShape expr = new BarShape(0, 0, 80, 20);  
    expr.setLeftEnd(BarShape.TRIANGLE_IN);
    expr.setRightEnd(BarShape.TRIANGLE_OUT);
    expr.setRole(BlockShape.EXCEPTION);
    expr.setDisplayName("Exception");
    setNodeAttr(expr);
    setNodeColor(expr, EXCEPTION_FG, EXCEPTION_BG);
    TextShape text = null;
    text = makeTitleText("exception", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Exception");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    expr.layoutComponents();
    return expr;
  }

  protected BarShape makeInitializationShape() { 
    BarShape expr = new BarShape(0, 0, 80, 18);  
    expr.setLeftEnd(BarShape.WEDGE_OUT);
    expr.setRightEnd(BarShape.TRIANGLE_IN);
    expr.setRole(BlockShape.INITIALIZATION);
    expr.setDisplayName("Initialization");
    setNodeAttr(expr);
    setNodeColor(expr, INIT_FG, INIT_BG);
    TextShape text = null;
    text = makeTitleText("initialize", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Initialization");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    expr.layoutComponents();
    return expr;
  }

  protected BarShape makeIncrementShape() { 
    BarShape expr = new BarShape(0, 0, 80, 18);  
    expr.setLeftEnd(BarShape.TRIANGLE_IN);
    expr.setRightEnd(BarShape.TRIANGLE_IN);
    expr.setRole(BlockShape.INCREMENTATION);
    expr.setDisplayName("Incrementation");
    setNodeAttr(expr);
    setNodeColor(expr, INCR_FG, INCR_BG);
    TextShape text = null;
    text = makeTitleText("increment", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Incrementation");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    expr.layoutComponents();
    return expr;
  }

  protected BarShape makeIterableShape() { 
    BarShape expr = new BarShape(0, 0, 80, 18);  
    expr.setLeftEnd(BarShape.TRIANGLE_OUT);
    expr.setRightEnd(BarShape.TRIANGLE_IN);
    expr.setRole(BlockShape.ITERABLE);
    setNodeAttr(expr);
    setNodeColor(expr, INCR_FG, INCR_BG);
    TextShape text = null;
    text = makeTitleText("iterable", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Iterable Expression");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    expr.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    expr.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    expr.layoutComponents();
    return expr; 
  }

  protected BlockShape makeMethodShape(boolean ctor, boolean full) { 
    MethodBlock shape = new MethodBlock(0, 0, 300, 100, ctor);
    //shape.setBlockType(ctor ? BlockShape.CONSTRUCTOR_BLOCK : BlockShape.METHOD_BLOCK);
    setNodeAttr(shape);
    setNodeColor(shape, NODE_FG, NODE_BG);
    TextShape text = null;
    text = makeTitleText(ctor ? "ClassName" : "methodName", 
			 NODE_FONT, NODE_COLOR);
    text.setDisplayName(ctor ? "Class Name" : "Method Name");
    text.setRole(BlockShape.NAME);
    text.setMarkString(true);
    shape.addShape(text);

    if (!ctor) { 
      text = makeTitleText("ReturnType", NODE_FONT, NODE_COLOR);
      text.setDisplayName("Return Type");
      text.setMarkString(true);
      text.setRole(BlockShape.TYPE);
      shape.addShape(text);
    }

    int n = (full ? 4 : 2); 
    BlockShape[] blocks = new BlockShape[n];
    int i = 0; 

    // parameter box 
    BlockShape shape1 = new BlockShape();
    shape1.setBlockType(BlockShape.PARAMETER_LIST);
    setNodeAttr(shape1);
    setNodeColor(shape1, PARAM_FG, PARAM_BG);
    blocks[i++] = shape1; 

    if (full) { 
      // pre-condition
      shape1 = new BlockShape(); 
      shape1.setBlockType(BlockShape.METHOD_PRE);
      setNodeAttr(shape1);
      setNodeColor(shape1, NODE_FG, NODE_BG);
      blocks[i++] = shape1; 
    }

    // body 
    shape1 = new BlockShape(); 
    shape1.setBlockType(BlockShape.METHOD_BODY);
    setNodeAttr(shape1);
    setNodeColor(shape1, NODE_FG, NODE_BG);
    blocks[i++] = shape1; 

    if (full) { 
      // post-condition
      shape1 = new BlockShape(); 
      shape1.setBlockType(BlockShape.METHOD_POST);
      setNodeAttr(shape1);
      setNodeColor(shape1, NODE_FG, NODE_BG);
      blocks[i++] = shape1; 
    }

    shape.addBlocks(blocks); 
    //shape.layoutComponents();
    return shape; 
  }

  protected BlockShape makeClassShape(boolean full) { 
    ClassBlock shape = new ClassBlock(0, 0, 300, 100);
    //shape.setBlockType(BlockShape.CLASS_BLOCK);
    setNodeAttr(shape);
    setNodeColor(shape, CLASS_FG, CLASS_BG);
    TextShape text = null;
    text = makeTitleText("ClassName", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Class Name");
    text.setMarkString(true);
    text.setRole(BlockShape.NAME);
    shape.addShape(text);

    int n = (full ? 8 : 3); 
    BlockShape[] blocks = new BlockShape[n];
    int i = 0; 
    BlockShape shape1;

    if (full) { 
      // enum box
      shape1 = new BlockShape();
      shape1.setBlockType(BlockShape.ENUM_LIST);
      setNodeAttr(shape1);
      setNodeColor(shape1, ENUM_FG, ENUM_BG);
      blocks[i++] = shape1; 
    }

    if (full) { 
      // constant box
      shape1 = new BlockShape();
      shape1.setBlockType(BlockShape.CONSTANT_LIST);
      setNodeAttr(shape1);
      setNodeColor(shape1, ATTR_FG, ATTR_BG);
      blocks[i++] = shape1; 
    }

    // attribute box 
    shape1 = new BlockShape();
    shape1.setBlockType(BlockShape.ATTRIBUTE_LIST);
    setNodeAttr(shape1);
    setNodeColor(shape1, ATTR_FG, ATTR_BG);
    blocks[i++] = shape1; 

    if (full) { 
      // static attribute box
      shape1 = new BlockShape();
      shape1.setBlockType(BlockShape.STATIC_FIELD_LIST);
      setNodeAttr(shape1);
      setNodeColor(shape1, ATTR_FG, ATTR_BG);
      blocks[i++] = shape1; 
    }

    // constructor box
    shape1 = new BlockShape(); 
    shape1.setBlockType(BlockShape.CONSTRUCTOR_LIST);
    setNodeAttr(shape1);
    setNodeColor(shape1, OPER_FG, OPER_BG);
    blocks[i++] = shape1; 

    // method box
    shape1 = new BlockShape(); 
    shape1.setBlockType(BlockShape.METHOD_LIST);
    setNodeAttr(shape1);
    setNodeColor(shape1, OPER_FG, OPER_BG);
    blocks[i++] = shape1; 

    if (full) { 
      // static method box
      shape1 = new BlockShape(); 
      shape1.setBlockType(BlockShape.STATIC_METHOD_LIST);
      setNodeAttr(shape1);
      setNodeColor(shape1, OPER_FG, OPER_BG);
      blocks[i++] = shape1; 

      // inner class box 
      shape1 = new BlockShape(); 
      shape1.setBlockType(BlockShape.INNER_CLASS_LIST);
      setNodeAttr(shape1);
      setNodeColor(shape1, CLASS_FG, CLASS_BG);
      blocks[i++] = shape1; 
    }

    shape.addBlocks(blocks); 
    //shape.addShape(shape1); 
    //shape.layoutComponents();
    return shape; 
  }

  protected BlockShape makeImportListShape() { 
    BlockShape shape = new BlockShape(0, 0, 300, 80);
    setNodeAttr(shape);
    setNodeColor(shape, IMPORT_FG, IMPORT_BG);
    shape.setBlockType(BlockShape.IMPORT_LIST);
    shape.layoutComponents();
    return shape; 
  }

  protected SimpleStatementShape makeImportShape(boolean staticImport) { 
    SimpleStatementShape stmt = new SimpleStatementShape(0, 0, 150, 20);
    stmt.setDisplayName("Import");
    setNodeAttr(stmt);
    setNodeColor(stmt, IMPORT_FG, IMPORT_BG);
    TextShape text = null;
    if (staticImport) { 
      stmt.setStatementType(SimpleStatementShape.STATIC_IMPORT);
      text = makeTitleText("name", "import static ", null, NODE_FONT, NODE_COLOR);
      text.setDisplayName("Static Import");
    } else { 
      stmt.setStatementType(SimpleStatementShape.IMPORT);
      text = makeTitleText("name", "import ", null, NODE_FONT, NODE_COLOR);
      text.setDisplayName("Import");
    }
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected BlockShape makeEnumBlockShape() { 
    BlockShape shape = new BlockShape(0, 0, 150, 80);
    setNodeAttr(shape);
    setNodeColor(shape, ENUM_FG, ENUM_BG);
    shape.setBlockType(BlockShape.ENUM_BLOCK);
    shape.setShowAddButton(true);
    TextShape text = null;
    text = makeTitleText("EnumName", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Enum Name");
    text.setMarkString(true);
    text.setRole(BlockShape.NAME);
    shape.addShape(text);
    shape.layoutComponents();
    return shape; 
  }

  /*
  protected BlockShape makeEnumListShape() { 
    BlockShape shape = new BlockShape(0, 0, 300, 80);
    setNodeAttr(shape);
    setNodeColor(shape, ENUM_FG, ENUM_BG);
    shape.setBlockType(BlockShape.ENUM_LIST);
    shape.layoutComponents();
    return shape; 
  }
  */

  protected SimpleStatementShape makeEnumValueShape() { 
    SimpleStatementShape stmt = new SimpleStatementShape(0, 0, 120, 20);
    stmt.setDisplayName("Enum Value");
    setNodeAttr(stmt);
    setNodeColor(stmt, ENUM_FG, ENUM_BG);
    TextShape text = null;
    stmt.setStatementType(SimpleStatementShape.ENUMERATION);
    text = makeTitleText("value", null, null, NODE_FONT, NODE_COLOR);
    text.setDisplayName("Enum Value");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected SimpleStatementShape makeStatementShape() { 
    SimpleStatementShape stmt = new SimpleStatementShape(0, 0, 150, 20);
    stmt.setDisplayName("Statement");
    setNodeAttr(stmt);
    setNodeColor(stmt, NODE_FG, NODE_BG);
    TextShape text = null;
    text = makeTitleText("statement", true, NODE_FONT, NODE_COLOR);    
    text.setDisplayName("Statement");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected SimpleStatementShape makeParameterShape() { 
    SimpleStatementShape stmt = new SimpleStatementShape(0, 0, 150, 20);
    stmt.setDisplayName("Parameter");
    stmt.setStatementType(SimpleStatementShape.PARAMETER);
    setNodeAttr(stmt);
    setNodeColor(stmt, PARAM_FG, PARAM_BG);
    TextShape text = null;
    text = makeTitleText("Type parameterName", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Parameter");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected SimpleStatementShape makeAttributeShape() { 
    SimpleStatementShape stmt = new AttributeShape(0, 0, 150, 20);
    stmt.setDisplayName("Attribute");
    stmt.setStatementType(SimpleStatementShape.ATTRIBUTE);
    setNodeAttr(stmt);
    setNodeColor(stmt, PARAM_FG, PARAM_BG);
    TextShape text = null;
    text = makeTitleText("Type attributeName", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Attribute");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected SimpleStatementShape makeMethodDeclShape() { 
    SimpleStatementShape stmt = new MethodDeclShape(0, 0, 150, 20);
    stmt.setDisplayName("Method declaration");
    stmt.setStatementType(SimpleStatementShape.METHOD_DECL);
    setNodeAttr(stmt);
    setNodeColor(stmt, CLASS_FG, CLASS_BG);
    
    TextShape text = null;
    text = makeTitleText("ReturnType methodName", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Method declaration");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);   
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected SimpleStatementShape makeMethodDeclShape2() { 
    SimpleStatementShape stmt = new SimpleStatementShape(0, 0, 150, 20);
    stmt.setStatementType(SimpleStatementShape.METHOD_DECL);
    setNodeAttr(stmt);
    setNodeColor(stmt, CLASS_FG, CLASS_BG);
    /*
    TextShape text = null;
    text = makeTitleText("ReturnType methodName", null, "()", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Method declaration");
    text.setMarkString(true);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    */

    BoxLabel box = new BoxLabel(HORIZONTAL, LEFT);    
    TextShape text1 = null;
    text1 = makeTitleText("ReturnType", NODE_FONT, NODE_COLOR);
    text1.setDisplayName("Return type");
    text1.setMarkString(true);
    box.addShape(text1);
    TextShape text2 = null;
    text2 = makeTitleText("methodName", NODE_FONT, NODE_COLOR);
    text2.setDisplayName("Method name");
    text2.setMarkString(true);
    box.addShape(text2);
    //box.linkTextLines();
    box.setDetachable(false);
    box.setScalable(false);
    box.setSticky(true);
    box.doLayout();

    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, box);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  protected SimpleStatementShape makeConstructorDeclShape() { 
    SimpleStatementShape stmt = new SimpleStatementShape(0, 0, 150, 20);
    stmt.setDisplayName("Constructor declaration");
    stmt.setStatementType(SimpleStatementShape.CONSTRUCTOR_DECL);
    setNodeAttr(stmt);
    setNodeColor(stmt, CLASS_FG, CLASS_BG);
    TextShape text = null;
    text = makeTitleText("ClassName", NODE_FONT, NODE_COLOR);
    text.setDisplayName("Constructor declaration");
    text.setMarkString(true);
    setFillColor(text, Color.white);
    stmt.setLabel(DrawShapeConstants.ROLE_NODE_LABEL, text);
    stmt.setLabelPosition(GraphNodeBase.LABEL_POSITION_LEFT_ADJUST);
    stmt.layoutComponents();
    return stmt; 
  }

  public static final String TRANSPARENT_COLOR = "template.VisualClass.Transparent.color";

  public static final String NODE_FG    = "template.VisualClass.fg";
  public static final String NODE_BG    = "template.VisualClass.bg";
  public static final String NODE_FONT  = "template.VisualClass.Node.font";
  public static final String NODE_COLOR = "template.VisualClass.Node.color";

  public static final String BRANCH_FG  = "template.VisualClass.Branch.fg";
  public static final String BRANCH_BG  = "template.VisualClass.Branch.bg";

  public static final String CATCH_FG   = "template.VisualClass.Catch.fg";
  public static final String CATCH_BG   = "template.VisualClass.Catch.bg";

  public static final String TRUE_BRANCH_FG   = "template.VisualClass.TrueBranch.fg";
  public static final String TRUE_BRANCH_BG   = "template.VisualClass.TrueBranch.bg";
  public static final String FALSE_BRANCH_FG  = "template.VisualClass.FalseBranch.fg";
  public static final String FALSE_BRANCH_BG  = "template.VisualClass.FalseBranch.bg";

  public static final String EXPR_FG      = "template.VisualClass.Expression.fg";
  public static final String EXPR_BG      = "template.VisualClass.Expression.bg";
  public static final String COND_FG      = "template.VisualClass.Condition.fg";
  public static final String COND_BG      = "template.VisualClass.Condition.bg";
  public static final String INIT_FG      = "template.VisualClass.Initialization.fg";
  public static final String INIT_BG      = "template.VisualClass.Initialization.bg";
  public static final String INCR_FG      = "template.VisualClass.Incrementation.fg";
  public static final String INCR_BG      = "template.VisualClass.Incrementation.bg";
  public static final String PARAM_FG     = "template.VisualClass.Parameter.fg";
  public static final String PARAM_BG     = "template.VisualClass.Parameter.bg";
  public static final String EXCEPTION_FG = "template.VisualClass.Exception.fg";
  public static final String EXCEPTION_BG = "template.VisualClass.Exception.bg";

  public static final String CLASS_FG = "template.VisualClass.Class.fg";
  public static final String CLASS_BG = "template.VisualClass.Class.bg";
  public static final String ATTR_FG  = "template.VisualClass.Attribute.fg";
  public static final String ATTR_BG  = "template.VisualClass.Attribute.bg";
  public static final String OPER_FG  = "template.VisualClass.Method.fg";
  public static final String OPER_BG  = "template.VisualClass.Method.bg";

  public static final String IMPORT_FG = "template.VisualClass.Import.fg";
  public static final String IMPORT_BG = "template.VisualClass.Import.bg";

  public static final String ENUM_FG = "template.VisualClass.Enum.fg";
  public static final String ENUM_BG = "template.VisualClass.Enum.bg";

  public static final String HEADER_COLOR = "template.VisualClass.Header.color";
  public static final String HEADER_FONT  = "template.VisualClass.Header.font";

}
